﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using PmSoft.Core.Domain.Auth;
using PmSoft.Web.Abstractions.ErrorCode;

namespace PmSoft.Web.Abstractions.Attributes;

/// <summary>
/// 自定义授权过滤器，用于限制访问的控制器或方法仅允许特定用户类型的用户。
/// 通过检查 JWT Token 中的 "UserType" 声明，验证当前用户类型是否在允许的列表中。
/// </summary>
[Obsolete("请使用 RestrictAccessAttribute 替代，它提供了更完整的访问控制功能。")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RestrictUserTypeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
	/// <summary>
	/// 获取允许访问的用户类型列表。
	/// </summary>
	private readonly string[] _allowedUserTypes;

	/// <summary>
	/// 初始化 <see cref="RestrictUserTypeAttribute"/> 的新实例，指定允许的用户类型。
	/// </summary>
	/// <param name="allowedUserTypes">一个或多个允许的用户类型。若为空或 null，则抛出异常。</param>
	/// <exception cref="ArgumentNullException">当 <paramref name="allowedUserTypes"/> 为 null 或空数组时抛出。</exception>
	public RestrictUserTypeAttribute(params string[] allowedUserTypes)
		: base() // 调用基类的默认构造函数
	{

		_allowedUserTypes = allowedUserTypes;
		AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme; // 指定使用 JWT Bearer 认证方案
	}

	/// <summary>
	/// 在授权阶段执行过滤逻辑，检查当前用户类型是否在允许列表中。
	/// 如果用户未认证，返回 401 Unauthorized；如果用户类型不匹配，返回 403 Forbidden。
	/// </summary>
	/// <param name="context">授权过滤器上下文，包含当前请求的信息。</param>
	public void OnAuthorization(AuthorizationFilterContext context)
	{
		// 确保上下文有效
		if (context == null)
		{
			throw new ArgumentNullException(nameof(context));
		}

		var user = context.HttpContext.User;

		// 检查用户是否已通过认证
		if (user?.Identity?.IsAuthenticated != true)
		{
			context.Result = new JsonResult(ApiResult.Error("UNAUTHENTICATED", "身份验证失败，请提供有效的凭据"))
			{
				StatusCode = ErrorCodeManager.GetError("UNAUTHENTICATED").HttpStatus
			};
			return; // 返回 401，未认证
		}

		// 获取当前用户
		var currentUser = context.HttpContext.Items["CurrentUser"] as IAuthedUser;
		if (currentUser == null)
		{
			context.Result = new JsonResult(ApiResult.Error("UNAUTHENTICATED", "当前用户未设置，授权失败"))
			{
				StatusCode = ErrorCodeManager.GetError("UNAUTHENTICATED").HttpStatus
			};
			return;
		}

		// 如果用户类型为空或不在允许列表中，返回 403
		if (string.IsNullOrEmpty(currentUser.UserType)
			|| (_allowedUserTypes.Length > 0 && !_allowedUserTypes.Contains(currentUser.UserType)))
		{
			context.Result = new JsonResult(ApiResult.Error("FORBIDDEN", "当前用户类型不能访问该资源"))
			{
				StatusCode = ErrorCodeManager.GetError("FORBIDDEN").HttpStatus
			};
			return; // 返回 403，禁止访问
		}
	}
}